package com.jzlin.funhub.admin.service.article;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzlin.funhub.admin.common.enums.ArticleStatusEnum;
import com.jzlin.funhub.admin.mapper.ArticleMapper;
import com.jzlin.funhub.admin.model.dto.ArticlePageDTO;
import com.jzlin.funhub.admin.model.dto.ArticlePageParamsDTO;
import com.jzlin.funhub.admin.model.dto.ArticleRecentDTO;
import com.jzlin.funhub.admin.model.entity.Article;
import com.jzlin.funhub.admin.model.req.ArticlePageReq;
import com.jzlin.funhub.admin.model.req.ArticlePublishReq;
import com.jzlin.funhub.admin.model.req.ArticleRecentReq;
import com.jzlin.funhub.admin.model.req.ArticleSaveDraftReq;
import com.jzlin.funhub.admin.model.resp.ArticleDetailResp;
import com.jzlin.funhub.admin.service.system.SysUserService;
import com.jzlin.funhub.framework.core.exception.AppException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 博客文章表 服务实现类
 * </p>
 *
 * @author jzlin
 * @since 2025-07-15
 */
@Service
public class ArticleService extends ServiceImpl<ArticleMapper, Article> {

    @Autowired
    private ArticleStarService articleStarService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ArticleTagsRefService articleTagsRefService;

    /**
     * 分页查询文章
     *
     * @return
     */
    public Page<ArticlePageDTO> queryPage(ArticlePageReq req) {
        IPage<?> page = new Page<>(req.getCurrent(), req.getSize());

        ArticlePageParamsDTO params = new ArticlePageParamsDTO();
        params.setStatus(List.of(ArticleStatusEnum.PUBLISHED.getCode()));
        params.setAuthorId(req.getUserId());
        params.setCategoryId(req.getCategoryId());
        params.setTitleLike(req.getTitleLike());
        params.setTagId(req.getTagId());
        return this.baseMapper.queryPage(page, params);
    }

    /**
     * 最近文章（5条）
     *
     * @return
     */
    public List<ArticleRecentDTO> queryRecent(ArticleRecentReq req) {
        List<Article> queryRet = this.query()
                .orderByDesc("published_time")
                .eq(req.getAuthorId() != null, "author_id", req.getAuthorId())
                .last("limit 5").list();

        return queryRet.stream().map(ArticleRecentDTO::new).collect(Collectors.toList());
    }

    /**
     * 获取文章详情
     *
     * @param id 文章id
     * @return
     */
    @Transactional
    public ArticleDetailResp getDetail(Long id) {
        ArticleDetailResp resp = this.baseMapper.queryDetailById(id);
        resp.setHasStar(articleStarService.ifCurrentUserHasStar(id));
        //文章标签
        resp.setTags(articleTagsRefService.listTagsByArticleId(id));

        //浏览量+1
        increaseArticleViewCount(id);

        return resp;
    }

    /**
     * 文章浏览+1
     */
    public void increaseArticleViewCount(Long articleId) {
        this.update().eq("id", articleId).setIncrBy("view_count", 1).update();
    }

    /**
     * 文章收藏数量
     *
     * @param articleId 文件id
     * @param flag       true收藏 false取消收藏
     */
    public void updateArticleStarCount(Long articleId, boolean flag) {
        if (flag) {
            this.update().eq("id", articleId).setIncrBy("star_count", 1).update();
        } else {
            this.update().eq("id", articleId).setDecrBy("star_count", 1).update();
        }
    }

    /**
     * 文章评论+1
     */
    public void increaseArticleCommentCount(Long articleId) {
        this.update().eq("id", articleId).setIncrBy("comment_count", 1).update();
    }

    /**
     * 保存文章草稿
     *
     * @param req
     */
    public Long saveDraft(ArticleSaveDraftReq req) {
        Article article = new Article();
        article.setTitle(req.getTitle());
        article.setSummary(req.getSummary());
        article.setContent(req.getContent());
        article.setIsDraft(Boolean.FALSE);
        article.setCategoryId(req.getCategoryId());
        article.setAuthorId(StpUtil.getLoginIdAsLong());

        this.save(article);
        return article.getId();
    }

    /**
     * 发布文章
     *
     * @param req
     */
    @Transactional
    public Long publishNewArticle(ArticlePublishReq req) {
        Long loginUserId = StpUtil.getLoginIdAsLong();
        if (!sysUserService.getDetail(loginUserId).getAllowBlog()) {
            throw new AppException("没有权限发布文章！");
        }

        Article article = new Article();
        article.setTitle(req.getTitle());
        article.setSummary(req.getSummary());
        article.setContent(req.getContent());
        article.setIsDraft(Boolean.FALSE);
        article.setCategoryId(req.getCategoryId());
        article.setAuthorId(loginUserId);
        article.setCoverImage(req.getCoverImage());
        //自动发布
        article.setStatus(ArticleStatusEnum.PUBLISHED.getCode());
        article.setPublishedTime(new Date());
        //发布文章+1
        sysUserService.updateArticleCount(loginUserId, true);

        this.save(article);
        //保存文章标签
        articleTagsRefService.bindTagsForArticle(article.getId(), req.getTags());

        return article.getId();
    }
}
